package demo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.ObjectPostProcessor; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; import org.springframework.security.oauth2.provider.ClientDetails; import org.springframework.security.oauth2.provider.ClientDetailsService; import org.springframework.security.oauth2.provider.ClientRegistrationException; import org.springframework.security.oauth2.provider.client.BaseClientDetails; import java.sql.ResultSet; import java.sql.SQLException; /** * Easy to retrieve an access token using: * {@code curl -X POST -vu acme:acmesecret http://localhost:8002/auth/oauth/token -H "Accept: application/json" -d "password=password&username=jlong&grant_type=password&scope=read&client_secret=acmesecret&client_id=acme" } * * Then, send the access token to an OAuth2 secured REST resource using: * {@code curl http://localhost:8080/api -H "Authorization: Bearer _INSERT TOKEN_} * * @author Josh Long */ @Configuration @ComponentScan @EnableAutoConfiguration public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean UserDetailsService userDetailsService(JdbcTemplate jdbcTemplate) { RowMapper<User> userRowMapper = (rs, i) -> new User( rs.getString("ACCOUNT_NAME"), rs.getString("PASSWORD"), rs.getBoolean("ENABLED"), rs.getBoolean("ENABLED"), rs.getBoolean("ENABLED"), rs.getBoolean("ENABLED"), AuthorityUtils.createAuthorityList("ROLE_USER", "ROLE_ADMIN")); return username -> jdbcTemplate.queryForObject( "select * from ACCOUNT where ACCOUNT_NAME = ?", userRowMapper, username); } @Bean ClientDetailsService clientDetailsService(JdbcTemplate jdbcTemplate) { RowMapper<ClientDetails> clientDetailsRowMapper = (rs, i) -> { BaseClientDetails baseClientDetails = new BaseClientDetails( rs.getString("CLIENT_ID"), rs.getString("RESOURCE_IDS"), rs.getString("SCOPES"), rs.getString("GRANT_TYPES"), rs.getString("AUTHORITIES")); baseClientDetails.setClientSecret(rs.getString("CLIENT_SECRET")); return baseClientDetails; }; return clientId -> jdbcTemplate.queryForObject( "select * from CLIENT_DETAILS where CLIENT_ID=?", clientDetailsRowMapper, clientId); } @Bean AuthenticationManager authenticationManager( ObjectPostProcessor<Object> objectPostProcessor, UserDetailsService userDetailsService) throws Exception { AuthenticationManagerBuilder authenticationManagerBuilder = new AuthenticationManagerBuilder(objectPostProcessor); authenticationManagerBuilder.userDetailsService(userDetailsService); return authenticationManagerBuilder.getOrBuild(); } @Configuration @EnableAuthorizationServer static class OAuth2AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Autowired private ClientDetailsService clientDetailsService; @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.withClientDetails(clientDetailsService); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationManager); } @Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer.checkTokenAccess("permitAll()"); } } }